/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package analiseSintatica.Regras.Comandos;

import AnaliseLexicaFinal.EstruturaDeDados.LinkToken;
import analiseSintatica.ErroSintaticoException;
import analiseSintatica.Regras.Expressoes.RegraExpressao;
import analiseSintatica.Regras.Regra;
import analiseSintatica.estruturadados.NoArvore;

import java.util.LinkedList;

/**
 *
 * @author Ivo Romário
 * 
 */
public class RegraScanf extends Regra{


    protected static Regra instancia;

    protected String estrutura = "'scanf' '(' charconst {',' <expressao>}+ ')' ';'";

    
    /**
     * Construtor privado necessario ao singleton
     */
    private RegraScanf(){

    }

    /**
     * Retorna a unica instancia dessa classe.
     * @return
     */
    public static RegraScanf getInstance() {
        if (instancia == null) {
            instancia = new RegraScanf();
        }
        return (RegraScanf) instancia;

    }

    

    @Override
    public NoArvore analisar(LinkedList<LinkToken> listaTokens) throws ErroSintaticoException {

        ErroSintaticoException erros = new ErroSintaticoException();

         NoArvore naoTerminalScanf = new NoArvore("<scanf>", false);

         naoTerminalScanf.adicionaFilho(reconhecerScanf(listaTokens));

         try{
            naoTerminalScanf.adicionaFilho(reconheceLexema(listaTokens, "delimitador", "(",estrutura));
         }
         catch(ErroSintaticoException e){
         }

         try{
            naoTerminalScanf.adicionaFilho(reconheceToken(listaTokens, "charconst",estrutura));
         }
         catch(ErroSintaticoException e){
         }

         try{
             do{
                naoTerminalScanf.adicionaFilho(reconheceLexema(listaTokens, "delimitador", ",",estrutura));
                naoTerminalScanf.adicionaFilho(RegraExpressao.getInstance().analisar(listaTokens));
             } while (listaTokens.getFirst().getToken().equals("delimitador") && listaTokens.getFirst().getLexema().equals(","));
         }
         catch(ErroSintaticoException e){
         }

         try{
             naoTerminalScanf.adicionaFilho(reconheceLexema(listaTokens, "delimitador", ")",estrutura));
         }
         catch(ErroSintaticoException e){
         }

         try{
             naoTerminalScanf.adicionaFilho(reconheceLexema(listaTokens, "delimitador", ";",estrutura));
         }
         catch(ErroSintaticoException e){
         }

         if(erros.size() != 0){
            throw erros;
         }

         return naoTerminalScanf;
       
    }

    public NoArvore reconhecerScanf (LinkedList<LinkToken> listaTokens){

            listaTokens.removeFirst();
            return new NoArvore("scanf", true);
    }
    
    @Override
    protected void setPrimeiro() {
        this.primeiro.add("scanf");
    }

    @Override
    protected void setSeguinte() {
        seguinte = RegraCmd.getInstance().getSeguinte();
    }

}
